--- title: "05-MongoDB 副本集与分片" created: 2026-08-31 tags: - 项目筑基 --- # MongoDB 副本集与分片 > MongoDB 系统讲解第二篇:02 篇理论篇讲过集群的概念轮廓,这一篇落到机制——oplog、选举、读偏好与写关注,以及分片架构里最重要的"片键怎么选"。 ## 副本集:三种角色 ```text Primary(主) —— 所有写请求的入口 Secondary(从) —— 复制主的数据,可分担读;主挂了参与竞选 Arbiter(仲裁) —— 只有投票权没有数据,省资源凑奇数票(书里评价:能用真从库就别用仲裁者) ``` **oplog 是复制的核心**:主库的每个写操作记进一个固定大小的环形集合(local.oplog.rs),从库拉取并**幂等地重放**。固定大小意味着写太猛会把旧 oplog 冲掉——从库同步不上来就退回全量初始同步,生产要监控 oplog 窗口。 **选举**:主不可达时,有投票权的成员选出新主(类 Raft)。要点: - 投票成员数**奇数**(3 / 5 / 7) - `priority` 高的从库优先当选(可指定某台机器当主) - 大多数派存活才选得出主——**两台机器坏一台和坏一半不一样**,这就是为什么副本集最少 3 个数据节点 ## 读写关注:一致性旋钮 **readPreference(读走哪个节点)**: | 模式 | 读谁 | 场景 | | --- | --- | --- | | primary(默认) | 只读主 | 强一致读 | | primaryPreferred | 主优先,主挂读从 | 高可用兜底 | | secondary | 只读从 | 分析类查询,容忍旧数据 | | secondaryPreferred | 从优先 | 读写分离典型选择 | | nearest | 最近的 | 多地域部署 | **writeConcern**(写确认级别):`w: 1` 主确认就返回(快,可能丢);`w: "majority"` 多数派确认(安全,慢一点);配 `j: true` 再加日志落盘确认。**读级别和写级别的组合就是一致性与延迟的旋钮**——这是副本集篇最核心的一句话。 ## 分片架构:三个角色 ```text mongos(路由) —— 应用连它,按片键把请求路由到对应分片 config server —— 存元数据:哪些数据在哪个分片(路由表) shard —— 每个分片本身就是一个副本集(高可用是分片的前提) ``` ## 片键:分片里最重要的决定 片键(shard key)决定数据怎么分布,**选了之后改起来要重建集合**(除非在线 refine,且限制很多): | 片键类型 | 分布 | 优点 | 缺点 | | --- | --- | --- | --- | | 范围片键(如 userId 区间) | 相邻数据同分片 | 范围查询高效 | **单调递增键(时间戳)全写进最后一片=热点** | | 哈希片键 | 均匀打散 | 写入均匀 | 范围查询变广播 | | 复合片键 | 组合 | 兼顾 | 设计复杂 | **片键三条红线**(书里反复强调): 1. 基数要高(低基数字段,比如"性别",分不出几片) 2. 别用单调递增的值做范围片键(追加写入全打到最后一片) 3. 查询要带上片键(不带片键的查询变成"扇出到所有分片"的散射查询) **chunk 与均衡**:数据按片键切成 chunk(块),balancer 后台在各分片间搬 chunk 保持均衡;搬不动的超大块叫 **jumbo chunk**(片键选择不当的产物)。 > 💡 我的记忆锚点:副本集解决"**高可用 + 读扩展**",分片解决"**写与数据量**"——先副本集,真到瓶颈再分片;分片的第一道坎不是运维,是片键设计。MongoDB 8.0 前后版本的分片机制一直在演进(config server 主从等),动手前查当时官方文档。 --- ⬅️ [[04-MongoDB 索引与查询优化|04-MongoDB 索引与查询优化]] 🏠 [[00-数据库|00-数据库]] ➡️ [[06-MongoDB 数据建模与实战模式|06-MongoDB 数据建模与实战模式]]